#include "Enum.h"

#include <string.h>
#include <fan-llvm/core/Core.h>
#include "Type.h"
#include "UnsupportedErr.h"


Type* Enum_classType = NULL;
VTable* Enum_classVTable = NULL;


/**********************************************
 *
 * Methods and fields
 *
 **********************************************/


/* Void make(Int ordinal, Str name) */
void Enum_make(Enum* self, Int ordinal, Str* name)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Enum.make not implemented yet"));
}


/* Bool equals(Obj? obj) */
Bool Enum_equals(Obj self, NullableObj obj)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Enum.equals not implemented yet"));
}


/* Int compare(Obj obj) */
Int Enum_compare(Obj self, Obj obj)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Enum.compare not implemented yet"));
}


/* Str toStr() */
Str* Enum_toStr(Obj self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Enum.toStr not implemented yet"));
}


/* Enum? doFromStr(Type t, Str name, Bool checked) */
Enum* Enum_doFromStr(Type* t, Str* name, Bool checked)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Enum.doFromStr not implemented yet"));
}


/* Str name() */
Str* Enum_name(Enum* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Enum.name not implemented yet"));
}


/* Int ordinal() */
Int Enum_ordinal(Enum* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Enum.ordinal not implemented yet"));
}


/**********************************************
 *
 * Type-system functions
 *
 **********************************************/


Type* Enum_initType(void)
{
  if (Enum_classType == NULL)
  {
    Type* baseType = Obj_initType();
    VTable* vtable = Enum_initVTable();
    Type* type = Type_new("Enum", baseType, vtable, sizeof(Enum), sizeof(EnumVTable));
    Type_registerCtorImplementation(type, "make", Enum_make, 2);
    Type_registerMethodImplementation(type, "compare", Enum_compare, 1);
    Type_registerMethodImplementation(type, "doFromStr", Enum_doFromStr, 3);
    Type_registerMethodImplementation(type, "equals", Enum_equals, 1);
    Type_registerMethodImplementation(type, "name", Enum_name, 0);
    Type_registerMethodImplementation(type, "ordinal", Enum_ordinal, 0);
    Type_registerMethodImplementation(type, "toStr", Enum_toStr, 0);
    Enum_classType = type;
    Enum_initStatic();
  }
  return Enum_classType;
}


VTable* Enum_initVTable(void)
{
  if (Enum_classVTable == NULL)
  {
    VTable* vtable = memoryAlloc(sizeof(EnumVTable));
    memcpy(vtable, Obj_initVTable(), sizeof(FanObjVTable));
    ((FanObjVTable*)vtable)->compare = Enum_compare;
    ((FanObjVTable*)vtable)->equals = Enum_equals;
    ((FanObjVTable*)vtable)->toStr = Enum_toStr;
    Enum_classVTable = vtable;
  }
  return Enum_classVTable;
}


void Enum_initStatic(void)
{
}
